#pragma once

#ifndef __HWINLOCALE_H__
#define __HWINLOCALE_H__

#include "hwinstring.h"
#include "hwinexception.h"

namespace harlinn
{
    namespace windows
    {

        enum class CurrencySymbolPosition
        {
            Prefix = 0,
            Suffix = 1,
            PrefixWithSeparator = 2,
            SuffixWithSeparator = 3
        };


        enum class DateFormat
        {
            MonthDayYear,
            DayMonthYear,
            YearMonthDay
        };

        enum class DigitSubstitution
        {
            Context = 0,
            None = 1,
            National = 2
        };

        enum class MeasurementSystem
        {
            SI = 0,
            US = 1
        };

        enum class NegativePercentFormat
        {
            SignNumberSpacePercent = 0,
            SignNumberPercent = 1,
            SignPercentNumber = 2,
            PercentSignNumber = 3,
            PercentNumberSign = 4,
            NumberSignPercent = 5,
            NumberPercentSign = 6,
            SignPercentSpaceNumber = 7,
            NumberSpacePercentSign = 8,
            PercentSpaceNumberSign = 9,
            PercentSpaceSignNumber = 10,
            NumberSignSpacePercent = 11
        };

        enum class PositivePercentFormat
        {
            NumberSpacePercent = 0,
            NumberPercent = 1,
            PercentNumber = 2,
            PercentSpaceNumber = 3
        };



        enum class NegativeCurrencyFormat
        {
            LeftParenthesisMonetarySymbolNumberRightParenthesis = 0,
            SignMonetarySymbolNumber = 1,
            MonetarySymbolSignNumber = 2,
            MonetarySymbolNumberSign = 3,
            LeftParenthesisNumberMonetarySymbolRightParenthesis = 4,
            SignNumberMonetarySymbol = 5,
            NumberSignMonetarySymbol = 6,
            NumberMonetarySymbolSign = 7,
            SignNumberSpaceMonetarySymbol = 8,
            SignMonetarySymbolSpaceNumber = 9,
            NumberSpaceMonetarySymbolSign = 10,
            MonetarySymbolSpaceNumberSign = 11,
            MonetarySymbolSpaceSignNumber = 12,
            NumberSignSpaceMonetarySymbol = 13,
            LeftParenthesisMonetarySymbolSpaceNumberRightParenthesis = 14,
            LeftParenthesisNumberSpaceMonetarySymbolRightParenthesis = 15
        };

        enum class NegativeNumberFormat
        {
            LeftParenthesisNumberRightParenthesis = 0,
            SignNumber = 1,
            SignSpaceNumber = 2,
            NumberSign = 3,
            NumberSpaceSign = 4
        };

        enum class SignPosition
        {
            Parentheses = 0,
            PrefixNumber = 1,
            SuffixNumber = 2,
            PrefixMonetarySymbol = 3,
            SuffixMonetarySymbol = 4
        };

        enum class LocaleReadingLayout
        {
            LeftToRight,
            RightToLeft,
            TopToBottomRightToLeft,
            TopToBottomLeftToRight
        };




        class Locale
        {
            class Data
            {
                long referenceCount;
                wchar_t* name;
            public:
                HWIN_EXPORT Data();
                HWIN_EXPORT Data(const wchar_t* theName);
                HWIN_EXPORT Data(const String& theName);
                HWIN_EXPORT ~Data();

                long AddRef()
                {
                    return InterlockedIncrement(&referenceCount);
                }

                long Release()
                {
                    long result = InterlockedDecrement(&referenceCount);
                    if(!result)
                    {
                        delete this;
                    }
                    return result;
                }


                HWIN_EXPORT String GetLocaleString(LCTYPE lctype) const;
                HWIN_EXPORT DWORD GetLocaleValue(LCTYPE lctype) const;

                HWIN_EXPORT LOCALESIGNATURE GetLocaleSignature() const;
                HWIN_EXPORT DWORD GetCalendarType() const;
                // if true short dates use 4 digits for century
                HWIN_EXPORT bool GetCentury() const;
                HWIN_EXPORT DWORD GetCountryRegionCode() const;
                HWIN_EXPORT DWORD GetNumberOfFractionalDigitsForCurrency() const;
                HWIN_EXPORT CurrencySymbolPosition GetCurrencySymbolPosition() const;
                HWIN_EXPORT DateFormat GetDateFormat() const;
                HWIN_EXPORT bool GetLeadingZeroForDays() const;
                HWIN_EXPORT DWORD GetDefaultAnsiCodePage() const;
                HWIN_EXPORT DWORD GetDefaultCodePage() const;
                HWIN_EXPORT DWORD GetDefaultEBCDICCodePage() const;
                HWIN_EXPORT DWORD GetDefaultMacCodePage() const;
                HWIN_EXPORT DWORD GetNumberOfFractionalDigits() const;
                HWIN_EXPORT DigitSubstitution GetDigitSubstitution() const;
                HWIN_EXPORT DWORD GetFirstDayOfWeek() const;
                HWIN_EXPORT DWORD GetFirstWeekOfYear() const;
                HWIN_EXPORT int GetGeoId() const;
                HWIN_EXPORT DWORD GetNumberOfFractionalDigitsForInternationalCurrency() const;
                HWIN_EXPORT DWORD GetLanguageId() const;
                HWIN_EXPORT DateFormat GetLongDateFormat() const;
                HWIN_EXPORT bool GetLeadingZeros() const;
                HWIN_EXPORT MeasurementSystem GetMeasurementSystem() const;
                HWIN_EXPORT bool GetLeadingZeroForMonths() const;
                HWIN_EXPORT NegativePercentFormat GetNegativePercentFormat() const;
                HWIN_EXPORT NegativeCurrencyFormat GetNegativeCurrencyFormat() const;
                HWIN_EXPORT NegativeNumberFormat GetNegativeNumberFormat() const;
                HWIN_EXPORT SignPosition GetNegativeSignPosition() const;
                HWIN_EXPORT bool GetMonetarySymbolAndNegativeNumberSeparatedBySpace() const;
                HWIN_EXPORT bool GetMonetarySymbolPrecedesNegativeAmount() const;
                HWIN_EXPORT DWORD GetOptionalCalendarType() const;
                HWIN_EXPORT DWORD GetPaperSize() const;
                HWIN_EXPORT PositivePercentFormat GetPositivePercentFormat() const;
                HWIN_EXPORT SignPosition GetPositiveSignPosition() const;
                HWIN_EXPORT bool GetMonetarySymbolAndNumberSeparatedBySpace() const;
                HWIN_EXPORT bool GetMonetarySymbolPrecedesAmount() const;
                HWIN_EXPORT LocaleReadingLayout GetLocaleReadingLayout() const;
                HWIN_EXPORT bool Get24HourClock() const;
                HWIN_EXPORT bool GetTimeMarkerAsPrefix() const;
                HWIN_EXPORT bool GetLeadingZeroForHours() const;
                HWIN_EXPORT String GetFirstTimeMarker() const;
                HWIN_EXPORT String GetSecondTimeMarker() const;
                HWIN_EXPORT String GetAbbreviatedCountryOrRegionName() const;
                HWIN_EXPORT String GetAbbreviatedLanguageName() const;
                HWIN_EXPORT String GetAbbreviatedMonthName(DWORD month) const;
                HWIN_EXPORT String GetAbbreviatedDayName(DWORD day) const;
                HWIN_EXPORT String GetMonthName(DWORD month) const;
                HWIN_EXPORT String GetGenetiveMonthName(DWORD month) const;
                HWIN_EXPORT String GetDayName(DWORD day) const;
                HWIN_EXPORT String GetShortDayName(DWORD day) const;
                HWIN_EXPORT String GetCurrencySymbol() const;
                HWIN_EXPORT String GetDateSeparator() const;
                HWIN_EXPORT String GetDecimalSeparator() const;
                HWIN_EXPORT String GetDurationFormat() const;
                HWIN_EXPORT String GetEnglishCountryOrRegionName() const;
                HWIN_EXPORT String GetEnglishCurrencyName() const;
                HWIN_EXPORT String GetEnglishLanguageName() const;
                HWIN_EXPORT String GetEnglishLocaleDisplayName() const;
                HWIN_EXPORT String GetDecimalGroups() const;
                HWIN_EXPORT String GetISO4217CurrencySymbol() const;
                HWIN_EXPORT String GetISO3166CountryName() const;
                HWIN_EXPORT String GetISO3166ThreeLetterCode() const;
                HWIN_EXPORT String GetISO639LanguageName() const;
                HWIN_EXPORT String GetISO639ThreeLetterLanguageName() const;
                HWIN_EXPORT String GetKeyboardNames() const;
                HWIN_EXPORT String GetLanguageDisplayName() const;
                HWIN_EXPORT String GetListSeparator() const;
                HWIN_EXPORT String GetLocalizedCountryName() const;
                HWIN_EXPORT String GetLocalizedDisplayName() const;
                HWIN_EXPORT String GetLocalizedLanguageName() const;
                HWIN_EXPORT String GetLongDateFormatString() const;
                HWIN_EXPORT String GetMonetaryDecimalSeparator() const;
                HWIN_EXPORT String GetMonetaryGrouping() const;
                HWIN_EXPORT String GetMonetaryThousandSeparator() const;
                HWIN_EXPORT String GetMonthDayFormatString() const;
                HWIN_EXPORT String GetName() const;
                HWIN_EXPORT String GetNan() const;
                HWIN_EXPORT String GetNativeCountryName() const;
                HWIN_EXPORT String GetNativeCurrencyName() const;
                HWIN_EXPORT String GetNativeDigits() const;
                HWIN_EXPORT String GetNativeLanguageName() const;
                HWIN_EXPORT String GetNativeDisplayName() const;
                HWIN_EXPORT String GetNegativeSign() const;
                HWIN_EXPORT String GetNegativeInfinity() const;
                HWIN_EXPORT String GetOpenTypeLanguageTag() const;
                HWIN_EXPORT String GetLocaleNameForSorting() const;
                HWIN_EXPORT String GetFallbackLocale() const;
                HWIN_EXPORT String GetPercent() const;
                HWIN_EXPORT String GetPermille() const;
                HWIN_EXPORT String GetPositiveInfinity() const;
                HWIN_EXPORT String GetPositiveSign() const;
                HWIN_EXPORT String GetScripts() const;
                HWIN_EXPORT String GetShortDateFormatString() const;
                HWIN_EXPORT String GetShortTimeFormatString() const;
                HWIN_EXPORT String GetLongTimeFormatString() const;
                HWIN_EXPORT String GetThousandSeparator() const;
                HWIN_EXPORT String GetYearMonthFormatString() const;
            };


            Data *data;
        public:
            HWIN_EXPORT static Locale Invariant;
            HWIN_EXPORT static Locale System;
            HWIN_EXPORT static Locale User;

            Locale()
                : data(0)
            {}

            Locale(const wchar_t* theName)
                : data(new Data(theName))
            {}
            Locale(const String& theName)
                : data(new Data(theName))
            {}


            Locale(const Locale& other)
                : data(other.data)
            {
                if(data)
                {
                    data->AddRef();
                }
            }

            Locale(Locale&& other)
                : data(other.data)
            {
                other.data = nullptr;
            }

            ~Locale()
            {
                if(data)
                {
                    data->Release();
                }
            }

            Locale& operator = (const Locale& other)
            {
                if(data != other.data)
                {
                    if(data)
                    {
                        data->Release();
                    }
                    data = other.data;
                    if(data)
                    {
                        data->AddRef();
                    }
                }
                return *this;
            }

            Locale& operator = (Locale&& other)
            {
                if(this != &other)
                {
                    if(data)
                    {
                        data->Release();
                    }
                    data = other.data;
                    other.data = nullptr;
                }
                return *this;
            }


            String GetLocaleString(LCTYPE lctype) const
            {
                if(data)
                {
                    return data->GetLocaleString(lctype);
                }
                else
                {
                    return User.GetLocaleString(lctype);
                }
            }
            DWORD GetLocaleValue(LCTYPE lctype) const
            {
                if(data)
                {
                    return data->GetLocaleValue(lctype);
                }
                else
                {
                    return User.GetLocaleValue(lctype);
                }
            }

            LOCALESIGNATURE GetLocaleSignature() const
            {
                if(data)
                {
                    return data->GetLocaleSignature();
                }
                else
                {
                    return User.GetLocaleSignature();
                }
            }


            DWORD GetCalendarType() const
            {
                if(data)
                {
                    return data->GetCalendarType();
                }
                else
                {
                    return User.GetCalendarType();
                }
            }

            bool GetCentury() const
            {
                if(data)
                {
                    return data->GetCentury();
                }
                else
                {
                    return User.GetCentury();
                }
            }

            DWORD GetCountryRegionCode() const
            {
                if(data)
                {
                    return data->GetCountryRegionCode();
                }
                else
                {
                    return User.GetCountryRegionCode();
                }
            }

            DWORD GetNumberOfFractionalDigitsForCurrency() const
            {
                if(data)
                {
                    return data->GetNumberOfFractionalDigitsForCurrency();
                }
                else
                {
                    return User.GetNumberOfFractionalDigitsForCurrency();
                }
            }

            CurrencySymbolPosition GetCurrencySymbolPosition() const
            {
                if(data)
                {
                    return data->GetCurrencySymbolPosition();
                }
                else
                {
                    return User.GetCurrencySymbolPosition();
                }
            }

            DateFormat GetDateFormat() const
            {
                if(data)
                {
                    return data->GetDateFormat();
                }
                else
                {
                    return User.GetDateFormat();
                }
            }

            bool GetLeadingZeroForDays() const
            {
                if(data)
                {
                    return data->GetLeadingZeroForDays();
                }
                else
                {
                    return User.GetLeadingZeroForDays();
                }
            }

            DWORD GetDefaultAnsiCodePage() const
            {
                if(data)
                {
                    return data->GetDefaultAnsiCodePage();
                }
                else
                {
                    return User.GetDefaultAnsiCodePage();
                }
            }

            DWORD GetDefaultCodePage() const
            {
                if(data)
                {
                    return data->GetDefaultCodePage();
                }
                else
                {
                    return User.GetDefaultCodePage();
                }
            }

            DWORD GetDefaultEBCDICCodePage() const
            {
                if(data)
                {
                    return data->GetDefaultEBCDICCodePage();
                }
                else
                {
                    return User.GetDefaultEBCDICCodePage();
                }
            }

            DWORD GetDefaultMacCodePage() const
            {
                if(data)
                {
                    return data->GetDefaultMacCodePage();
                }
                else
                {
                    return User.GetDefaultMacCodePage();
                }
            }

            DWORD GetNumberOfFractionalDigits() const
            {
                if(data)
                {
                    return data->GetNumberOfFractionalDigits();
                }
                else
                {
                    return User.GetNumberOfFractionalDigits();
                }
            }

            DigitSubstitution GetDigitSubstitution() const
            {
                if(data)
                {
                    return data->GetDigitSubstitution();
                }
                else
                {
                    return User.GetDigitSubstitution();
                }
            }

            DWORD GetFirstDayOfWeek() const
            {
                if(data)
                {
                    return data->GetFirstDayOfWeek();
                }
                else
                {
                    return User.GetFirstDayOfWeek();
                }
            }

            DWORD GetFirstWeekOfYear() const
            {
                if(data)
                {
                    return data->GetFirstWeekOfYear();
                }
                else
                {
                    return User.GetFirstWeekOfYear();
                }
            }

            int GetGeoId() const
            {
                if(data)
                {
                    return data->GetGeoId();
                }
                else
                {
                    return User.GetGeoId();
                }
            }

            DWORD GetNumberOfFractionalDigitsForInternationalCurrency() const
            {
                if(data)
                {
                    return data->GetNumberOfFractionalDigitsForInternationalCurrency();
                }
                else
                {
                    return User.GetNumberOfFractionalDigitsForInternationalCurrency();
                }
            }

            DWORD GetLanguageId() const
            {
                if(data)
                {
                    return data->GetLanguageId();
                }
                else
                {
                    return User.GetLanguageId();
                }
            }

            DateFormat GetLongDateFormat() const
            {
                if(data)
                {
                    return data->GetLongDateFormat();
                }
                else
                {
                    return User.GetLongDateFormat();
                }
            }

            bool GetLeadingZeros() const
            {
                if(data)
                {
                    return data->GetLeadingZeros();
                }
                else
                {
                    return User.GetLeadingZeros();
                }
            }

            MeasurementSystem GetMeasurementSystem() const
            {
                if(data)
                {
                    return data->GetMeasurementSystem();
                }
                else
                {
                    return User.GetMeasurementSystem();
                }
            }

            bool GetLeadingZeroForMonths() const
            {
                if(data)
                {
                    return data->GetLeadingZeroForMonths();
                }
                else
                {
                    return User.GetLeadingZeroForMonths();
                }
            }

            NegativePercentFormat GetNegativePercentFormat() const
            {
                if(data)
                {
                    return data->GetNegativePercentFormat();
                }
                else
                {
                    return User.GetNegativePercentFormat();
                }
            }

            NegativeCurrencyFormat GetNegativeCurrencyFormat() const
            {
                if(data)
                {
                    return data->GetNegativeCurrencyFormat();
                }
                else
                {
                    return User.GetNegativeCurrencyFormat();
                }
            }

            NegativeNumberFormat GetNegativeNumberFormat() const
            {
                if(data)
                {
                    return data->GetNegativeNumberFormat();
                }
                else
                {
                    return User.GetNegativeNumberFormat();
                }
            }

            SignPosition GetNegativeSignPosition() const
            {
                if(data)
                {
                    return data->GetNegativeSignPosition();
                }
                else
                {
                    return User.GetNegativeSignPosition();
                }
            }

            bool GetMonetarySymbolAndNegativeNumberSeparatedBySpace() const
            {
                if(data)
                {
                    return data->GetMonetarySymbolAndNegativeNumberSeparatedBySpace();
                }
                else
                {
                    return User.GetMonetarySymbolAndNegativeNumberSeparatedBySpace();
                }
            }

            bool GetMonetarySymbolPrecedesNegativeAmount() const
            {
                if(data)
                {
                    return data->GetMonetarySymbolPrecedesNegativeAmount();
                }
                else
                {
                    return User.GetMonetarySymbolPrecedesNegativeAmount();
                }
            }

            DWORD GetOptionalCalendarType() const
            {
                if(data)
                {
                    return data->GetOptionalCalendarType();
                }
                else
                {
                    return User.GetOptionalCalendarType();
                }
            }

            DWORD GetPaperSize() const
            {
                if(data)
                {
                    return data->GetPaperSize();
                }
                else
                {
                    return User.GetPaperSize();
                }
            }

            PositivePercentFormat GetPositivePercentFormat() const
            {
                if(data)
                {
                    return data->GetPositivePercentFormat();
                }
                else
                {
                    return User.GetPositivePercentFormat();
                }
            }

            SignPosition GetPositiveSignPosition() const
            {
                if(data)
                {
                    return data->GetPositiveSignPosition();
                }
                else
                {
                    return User.GetPositiveSignPosition();
                }
            }

            bool GetMonetarySymbolAndNumberSeparatedBySpace() const
            {
                if(data)
                {
                    return data->GetMonetarySymbolAndNumberSeparatedBySpace();
                }
                else
                {
                    return User.GetMonetarySymbolAndNumberSeparatedBySpace();
                }
            }

            bool GetMonetarySymbolPrecedesAmount() const
            {
                if(data)
                {
                    return data->GetMonetarySymbolPrecedesAmount();
                }
                else
                {
                    return User.GetMonetarySymbolPrecedesAmount();
                }
            }

            LocaleReadingLayout GetLocaleReadingLayout() const
            {
                if(data)
                {
                    return data->GetLocaleReadingLayout();
                }
                else
                {
                    return User.GetLocaleReadingLayout();
                }
            }

            bool Get24HourClock() const
            {
                if(data)
                {
                    return data->Get24HourClock();
                }
                else
                {
                    return User.Get24HourClock();
                }
            }

            bool GetTimeMarkerAsPrefix() const
            {
                if(data)
                {
                    return data->GetTimeMarkerAsPrefix();
                }
                else
                {
                    return User.GetTimeMarkerAsPrefix();
                }
            }

            bool GetLeadingZeroForHours() const
            {
                if(data)
                {
                    return data->GetLeadingZeroForHours();
                }
                else
                {
                    return User.GetLeadingZeroForHours();
                }
            }

            String GetFirstTimeMarker() const
            {
                if(data)
                {
                    return data->GetFirstTimeMarker();
                }
                else
                {
                    return User.GetFirstTimeMarker();
                }
            }

            String GetSecondTimeMarker() const
            {
                if(data)
                {
                    return data->GetSecondTimeMarker();
                }
                else
                {
                    return User.GetSecondTimeMarker();
                }
            }

            String GetAbbreviatedCountryOrRegionName() const
            {
                if(data)
                {
                    return data->GetAbbreviatedCountryOrRegionName();
                }
                else
                {
                    return User.GetAbbreviatedCountryOrRegionName();
                }
            }

            String GetAbbreviatedLanguageName() const
            {
                if(data)
                {
                    return data->GetAbbreviatedLanguageName();
                }
                else
                {
                    return User.GetAbbreviatedLanguageName();
                }
            }

            String GetAbbreviatedMonthName(DWORD month) const
            {
                if(data)
                {
                    return data->GetAbbreviatedMonthName(month);
                }
                else
                {
                    return User.GetAbbreviatedMonthName(month);
                }
            }

            String GetAbbreviatedDayName(DWORD day) const
            {
                if(data)
                {
                    return data->GetAbbreviatedDayName(day);
                }
                else
                {
                    return User.GetAbbreviatedDayName(day);
                }
            }

            String GetMonthName(DWORD month) const
            {
                if(data)
                {
                    return data->GetMonthName(month);
                }
                else
                {
                    return User.GetMonthName(month);
                }
            }

            String GetGenetiveMonthName(DWORD month) const
            {
                if(data)
                {
                    return data->GetGenetiveMonthName(month);
                }
                else
                {
                    return User.GetGenetiveMonthName(month);
                }
            }

            String GetDayName(DWORD day) const
            {
                if(data)
                {
                    return data->GetDayName(day);
                }
                else
                {
                    return User.GetDayName(day);
                }
            }

            String GetShortDayName(DWORD day) const
            {
                if(data)
                {
                    return data->GetShortDayName(day);
                }
                else
                {
                    return User.GetShortDayName(day);
                }
            }

            String GetCurrencySymbol() const
            {
                if(data)
                {
                    return data->GetCurrencySymbol();
                }
                else
                {
                    return User.GetCurrencySymbol();
                }
            }

            String GetDateSeparator() const
            {
                if(data)
                {
                    return data->GetDateSeparator();
                }
                else
                {
                    return User.GetDateSeparator();
                }
            }

            String GetDecimalSeparator() const
            {
                if(data)
                {
                    return data->GetDecimalSeparator();
                }
                else
                {
                    return User.GetDecimalSeparator();
                }
            }

            String GetDurationFormat() const
            {
                if(data)
                {
                    return data->GetDurationFormat();
                }
                else
                {
                    return User.GetDurationFormat();
                }
            }

            String GetEnglishCountryOrRegionName() const
            {
                if(data)
                {
                    return data->GetEnglishCountryOrRegionName();
                }
                else
                {
                    return User.GetEnglishCountryOrRegionName();
                }
            }

            String GetEnglishCurrencyName() const
            {
                if(data)
                {
                    return data->GetEnglishCurrencyName();
                }
                else
                {
                    return User.GetEnglishCurrencyName();
                }
            }

            String GetEnglishLanguageName() const
            {
                if(data)
                {
                    return data->GetEnglishLanguageName();
                }
                else
                {
                    return User.GetEnglishLanguageName();
                }
            }

            String GetEnglishLocaleDisplayName() const
            {
                if(data)
                {
                    return data->GetEnglishLocaleDisplayName();
                }
                else
                {
                    return User.GetEnglishLocaleDisplayName();
                }
            }

            String GetDecimalGroups() const
            {
                if(data)
                {
                    return data->GetDecimalGroups();
                }
                else
                {
                    return User.GetDecimalGroups();
                }
            }

            String GetISO4217CurrencySymbol() const
            {
                if(data)
                {
                    return data->GetISO4217CurrencySymbol();
                }
                else
                {
                    return User.GetISO4217CurrencySymbol();
                }
            }

            String GetISO3166CountryName() const
            {
                if(data)
                {
                    return data->GetISO3166CountryName();
                }
                else
                {
                    return User.GetISO3166CountryName();
                }
            }

            String GetISO3166ThreeLetterCode() const
            {
                if(data)
                {
                    return data->GetISO3166ThreeLetterCode();
                }
                else
                {
                    return User.GetISO3166ThreeLetterCode();
                }
            }

            String GetISO639LanguageName() const
            {
                if(data)
                {
                    return data->GetISO639LanguageName();
                }
                else
                {
                    return User.GetISO639LanguageName();
                }
            }

            String GetISO639ThreeLetterLanguageName() const
            {
                if(data)
                {
                    return data->GetISO639ThreeLetterLanguageName();
                }
                else
                {
                    return User.GetISO639ThreeLetterLanguageName();
                }
            }

            String GetKeyboardNames() const
            {
                if(data)
                {
                    return data->GetKeyboardNames();
                }
                else
                {
                    return User.GetKeyboardNames();
                }
            }

            String GetLanguageDisplayName() const
            {
                if(data)
                {
                    return data->GetLanguageDisplayName();
                }
                else
                {
                    return User.GetLanguageDisplayName();
                }
            }

            String GetListSeparator() const
            {
                if(data)
                {
                    return data->GetListSeparator();
                }
                else
                {
                    return User.GetListSeparator();
                }
            }

            String GetLocalizedCountryName() const
            {
                if(data)
                {
                    return data->GetLocalizedCountryName();
                }
                else
                {
                    return User.GetLocalizedCountryName();
                }
            }

            String GetLocalizedDisplayName() const
            {
                if(data)
                {
                    return data->GetLocalizedDisplayName();
                }
                else
                {
                    return User.GetLocalizedDisplayName();
                }
            }

            String GetLocalizedLanguageName() const
            {
                if(data)
                {
                    return data->GetLocalizedLanguageName();
                }
                else
                {
                    return User.GetLocalizedLanguageName();
                }
            }

            String GetLongDateFormatString() const
            {
                if(data)
                {
                    return data->GetLongDateFormatString();
                }
                else
                {
                    return User.GetLongDateFormatString();
                }
            }

            String GetMonetaryDecimalSeparator() const
            {
                if(data)
                {
                    return data->GetMonetaryDecimalSeparator();
                }
                else
                {
                    return User.GetMonetaryDecimalSeparator();
                }
            }

            String GetMonetaryGrouping() const
            {
                if(data)
                {
                    return data->GetMonetaryGrouping();
                }
                else
                {
                    return User.GetMonetaryGrouping();
                }
            }

            String GetMonetaryThousandSeparator() const
            {
                if(data)
                {
                    return data->GetMonetaryThousandSeparator();
                }
                else
                {
                    return User.GetMonetaryThousandSeparator();
                }
            }

            String GetMonthDayFormatString() const
            {
                if(data)
                {
                    return data->GetMonthDayFormatString();
                }
                else
                {
                    return User.GetMonthDayFormatString();
                }
            }

            String GetName() const
            {
                if(data)
                {
                    return data->GetName();
                }
                else
                {
                    return User.GetName();
                }
            }

            String GetNan() const
            {
                if(data)
                {
                    return data->GetNan();
                }
                else
                {
                    return User.GetNan();
                }
            }

            String GetNativeCountryName() const
            {
                if(data)
                {
                    return data->GetNativeCountryName();
                }
                else
                {
                    return User.GetNativeCountryName();
                }
            }

            String GetNativeCurrencyName() const
            {
                if(data)
                {
                    return data->GetNativeCurrencyName();
                }
                else
                {
                    return User.GetNativeCurrencyName();
                }
            }

            String GetNativeDigits() const
            {
                if(data)
                {
                    return data->GetNativeDigits();
                }
                else
                {
                    return User.GetNativeDigits();
                }
            }

            String GetNativeLanguageName() const
            {
                if(data)
                {
                    return data->GetNativeLanguageName();
                }
                else
                {
                    return User.GetNativeLanguageName();
                }
            }

            String GetNativeDisplayName() const
            {
                if(data)
                {
                    return data->GetNativeDisplayName();
                }
                else
                {
                    return User.GetNativeDisplayName();
                }
            }

            String GetNegativeSign() const
            {
                if(data)
                {
                    return data->GetNegativeSign();
                }
                else
                {
                    return User.GetNegativeSign();
                }
            }

            String GetNegativeInfinity() const
            {
                if(data)
                {
                    return data->GetNegativeInfinity();
                }
                else
                {
                    return User.GetNegativeInfinity();
                }
            }

            String GetOpenTypeLanguageTag() const
            {
                if(data)
                {
                    return data->GetOpenTypeLanguageTag();
                }
                else
                {
                    return User.GetOpenTypeLanguageTag();
                }
            }

            String GetLocaleNameForSorting() const
            {
                if(data)
                {
                    return data->GetLocaleNameForSorting();
                }
                else
                {
                    return User.GetLocaleNameForSorting();
                }
            }

            String GetFallbackLocale() const
            {
                if(data)
                {
                    return data->GetFallbackLocale();
                }
                else
                {
                    return User.GetFallbackLocale();
                }
            }

            String GetPercent() const
            {
                if(data)
                {
                    return data->GetPercent();
                }
                else
                {
                    return User.GetPercent();
                }
            }

            String GetPermille() const
            {
                if(data)
                {
                    return data->GetPermille();
                }
                else
                {
                    return User.GetPermille();
                }
            }

            String GetPositiveInfinity() const
            {
                if(data)
                {
                    return data->GetPositiveInfinity();
                }
                else
                {
                    return User.GetPositiveInfinity();
                }
            }

            String GetPositiveSign() const
            {
                if(data)
                {
                    return data->GetPositiveSign();
                }
                else
                {
                    return User.GetPositiveSign();
                }
            }

            String GetScripts() const
            {
                if(data)
                {
                    return data->GetScripts();
                }
                else
                {
                    return User.GetScripts();
                }
            }

            String GetShortDateFormatString() const
            {
                if(data)
                {
                    return data->GetShortDateFormatString();
                }
                else
                {
                    return User.GetShortDateFormatString();
                }
            }

            String GetShortTimeFormatString() const
            {
                if(data)
                {
                    return data->GetShortTimeFormatString();
                }
                else
                {
                    return User.GetShortTimeFormatString();
                }
            }

            String GetLongTimeFormatString() const
            {
                if(data)
                {
                    return data->GetLongTimeFormatString();
                }
                else
                {
                    return User.GetLongTimeFormatString();
                }
            }

            String GetThousandSeparator() const
            {
                if(data)
                {
                    return data->GetThousandSeparator();
                }
                else
                {
                    return User.GetThousandSeparator();
                }
            }

            String GetYearMonthFormatString() const
            {
                if(data)
                {
                    return data->GetYearMonthFormatString();
                }
                else
                {
                    return User.GetYearMonthFormatString();
                }
            }



        };
    };
};


#endif //__HWINLOCALE_H__

